#ifndef	__BFX_REFDECODERFALLBACK_H__
#define	__BFX_REFDECODERFALLBACK_H__

namespace BFX
{

#ifndef	__UCHAR_TYPE_DEF__
#define	__UCHAR_TYPE_DEF__
typedef	unsigned short UCHAR;
#endif

//////////////////////////////////////////////////////////////////////////////
// Provides a buffer that allows a fallback handler to return an alternate string to a decoder when it cannot decode an input byte sequence. 
class BFX_API REFDecoderFallbackBuffer : public REFObject
{
public:
	// Initializes a new instance of the DecoderFallbackBuffer class.
	REFDecoderFallbackBuffer();
	virtual ~REFDecoderFallbackBuffer();

	// Prepares the fallback buffer to handle the specified input byte sequence.
	virtual bool Fallback(SequenceT<BYTE> bytesUnknown, int iOffset) = 0;

	// Retrieves the next character in the fallback buffer.
	virtual UCHAR GetNextChar() = 0;
	// Back up a character, move to the previous character position. 
	virtual bool MovePrevious() = 0;
	// Gets the number of characters in the current DecoderFallbackBuffer object that remain to be processed.
	virtual int GetRemaining() = 0;
	// Initializes all data and state information pertaining to this fallback buffer.
	virtual void Reset()
	{
		while (GetNextChar() != 0);
	}

	// Internal initializes the buffer.
	// This can't be part of the constructor because REFDecoderFallbacks would have to know how to impliment these.
	void Initialize(const BYTE* pByteStart, UCHAR* pCharEnd)
	{
		m_pByteStart = pByteStart;
		m_pCharEnd = pCharEnd;
	}
	bool Fallback(SequenceT<BYTE> bytesUnknown, const BYTE* pBytes, INOUT UCHAR*& pChars);

	// This version just counts the fallback and doesn't actually copy anything.
	int Fallback(SequenceT<BYTE> bytesUnknown, const BYTE* pBytes);
	void ResetAll()
	{
		m_pByteStart = NULL;
		Reset();
	}

protected:
	// Following variables to help us figure out what we're doing as far as error messages, etc.
	// These help us with our performance and messages internally
	const BYTE*		m_pByteStart;
	UCHAR*		m_pCharEnd;
};

//////////////////////////////////////////////////////////////////////////////
// Provides a failure-handling mechanism, called a fallback,
// for an encoded input byte sequence that cannot be converted to an output character. 
class BFX_API REFDecoderFallback : public REFObject
{
public:
	// Initializes / destroys a new instance of the DecoderFallback class.
	REFDecoderFallback();
	virtual ~REFDecoderFallback();

	// Initializes a new instance of the DecoderFallbackBuffer class. 
	virtual REFDecoderFallbackBuffer* CreateFallbackBuffer() = 0;
	// Gets the maximum number of characters the current DecoderFallback object can return.
	virtual int GetMaxCharCount() const = 0;
};

}

#endif	//	__BFX_REFDECODERFALLBACK_H__
